package com.example.webviewmodule

import android.content.Context
import android.opengl.GLES11Ext
import android.opengl.GLES20
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer
import java.util.*
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

class FooRenderer(val context: Context,width:Int,height:Int ):BaseWebGLRenderer(width,height){

    private var mCubePositions: FloatBuffer

    private var mCubeTextureCoordinates: FloatBuffer

    private var startTime: Long

    private var mProgramHandle: Int = 0
    private var mTimeHandle=0
    private var mTextureUniformHandle: Int=0
    init {
        mCubePositions=ByteBuffer.allocateDirect(cubePositionData.size*mBytesPerFloat).order(ByteOrder.nativeOrder())
            .asFloatBuffer()
        mCubePositions.put(cubePositionData).position(0)

        mCubeTextureCoordinates=ByteBuffer.allocateDirect(cubeTextureCoordinateData.size* mBytesPerFloat).order(
            ByteOrder.nativeOrder()).asFloatBuffer()
        mCubeTextureCoordinates.put(cubeTextureCoordinateData).position(0)

        startTime= Calendar.getInstance().timeInMillis


    }

    override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {
        super.onSurfaceCreated(gl, config)
        GLES20.glClearColor(0.0f,0.0f,1.0f,0.0f)

        val vertextShader=getVertexShader()
        val fragmentShader=getFragmentShader()
        val vertexShaderHandle=ShaderEx.compileShader(GLES20.GL_VERTEX_SHADER,vertextShader)
        val fragmentShaderHandle=ShaderEx.compileShader(GLES20.GL_FRAGMENT_SHADER,fragmentShader)

        mProgramHandle=ShaderEx.createAndLinProgram(vertexShaderHandle,fragmentShaderHandle,
            arrayOf("a_Position","a_TexCoordinate"))
    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        super.onSurfaceChanged(gl, width, height)
        GLES20.glViewport(0,0,width,height)
        this.mTextureWidth=width
        this.mTextureHeight=height
    }


    private var mResolutionHandle=0

    private var mPositionHandle=0

    private var mTextureCoordinateHandle=0

    override fun onDrawFrame(gl: GL10?) {
        super.onDrawFrame(gl)
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT or GLES20.GL_DEPTH_BUFFER_BIT)
        val currentProgramHandle=mProgramHandle
        GLES20.glUseProgram(currentProgramHandle)

        mTextureUniformHandle=GLES20.glGetUniformLocation(currentProgramHandle,"u_Texture")
        mTimeHandle=GLES20.glGetUniformLocation(currentProgramHandle,"u_GlobalTime")
        mResolutionHandle=GLES20.glGetUniformLocation(currentProgramHandle,"u_Resolution")

        mPositionHandle=GLES20.glGetAttribLocation(currentProgramHandle,"a_Position")
        mTextureCoordinateHandle=GLES20.glGetAttribLocation(currentProgramHandle,"a_TexCoordinate")

        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,mGlSurfaceTexture)
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
        GLES20.glUniform1i(mTextureUniformHandle,0)

        var timeInMs=Calendar.getInstance().timeInMillis-startTime

        if(timeInMs>20000){
            startTime=Calendar.getInstance().timeInMillis
        }

        GLES20.glUniform2f(mResolutionHandle,mTextureWidth.toFloat(),mTextureHeight.toFloat())
        GLES20.glUniform1f(mTimeHandle, (timeInMs/1000).toFloat())
        drawCube()

    }

    private val mPositionDataSize=3

    private val mTextureCoordinateDataSize=2

    private fun drawCube() {
        mCubePositions.position(0)

        GLES20.glVertexAttribPointer(mPositionHandle,mPositionDataSize,GLES20.GL_FLOAT,false,0,mCubePositions)

        GLES20.glEnableVertexAttribArray(mPositionHandle)

        mCubeTextureCoordinates.position(0)

        GLES20.glVertexAttribPointer(mTextureCoordinateHandle,mTextureCoordinateDataSize,GLES20.GL_FLOAT,false,0,mCubeTextureCoordinates)
        GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle)
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,6)
    }

    private fun getFragmentShader(): String {
        return RawResourceReader.readTextFileFromRawResource(context,R.raw.rect_fragment_shader)!!
    }

    private fun getVertexShader(): String {
        return RawResourceReader.readTextFileFromRawResource(context, R.raw.vertex_shader)!!
    }

    companion object {

        private val mBytesPerFloat=4
        val cubePositionData= floatArrayOf(
            -1.0f,1.0f,1.0f,
            -1.0f,-1.0f,1.0f,
            1.0f,1.0f,1.0f,
            -1.0f,-1.0f,1.0f,
            1.0f,-1.0f,1.0f,
            1.0f,1.0f,1.0f
        )

        val cubeTextureCoordinateData= floatArrayOf(
            0.0f,0.0f,
            0.0f,1.0f,
            1.0f,0.0f,
            0.0f,1.0f,
            1.0f,1.0f,
            1.0f,0.0f
        )
    }

}